package merchant.dao;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import hackathon1212.EMF;

import javax.persistence.EntityManager;
import javax.persistence.Query;

public class MerchantDAO {

	/*
	 * We keep track of the merchants, because GAE object store doesn't support "get a random entity".
	 * Otherwise we would have to fecth all the merchants each time, it doesn't really matter 
	 * if we don't have the most up to date list!
	 *  
	 */
	private List<Merchant> merchants = new LinkedList<Merchant>();
	
	private MerchantDAO(){
		final EntityManager em = EMF.get().createEntityManager();
		try{
			final Query q = em.createQuery("select m from Merchant m ");
			merchants.addAll(q.getResultList());
		} finally {
			em.close();
		}
	}
	private static MerchantDAO singleton = new MerchantDAO();
	public static MerchantDAO get(){
		return singleton;
	}
	
	public Merchant getByMerchantNumber(final String merchantNumber){
		final EntityManager em = EMF.get().createEntityManager();
		try{
			return em.find(Merchant.class, merchantNumber);
		} finally {
			em.close();
		}
	}
	
	public void saveMerchant(final Merchant merchant){
		final EntityManager em = EMF.get().createEntityManager();
		try{
			em.merge(merchant);
			merchants.add(merchant);
		} finally {
			em.close();
		}
	}
	@SuppressWarnings("unchecked")
	public List<MerchantSettlementDetail> findSettlements(final String merchantNumber, final Date fromInclusiveDate, final Date toExclusiveDate){
		final EntityManager em = EMF.get().createEntityManager();
		final List<MerchantSettlementDetail> ret;
		try{
			final Query q = em.createQuery("select settlement from MerchantSettlementDetail settlement where " +
											"settlement.merchantNumber = :MERCHANT " +
											"and settlement.settlementDate >= :FROM " +
											"and settlement.settlementDate < :TO");
			q.setParameter("MERCHANT", merchantNumber);
			q.setParameter("FROM", fromInclusiveDate);
			q.setParameter("TO", toExclusiveDate);
			ret =  q.getResultList();
		} finally {
			em.close();
		}
		for(final MerchantSettlementDetail sd : ret){
			final List<SummaryOfCharge> socs = ChargeDAO.get().getSOCBySettlementId(sd.getSettlementId());
			float sum = 0;
			for(final SummaryOfCharge soc : socs){
				sum += soc.getAmount();
			}
			sd.setSettlementLocalAmount(sum);
		}
		return ret;
	}

	public MerchantSettlementDetail saveSettlementDetail(MerchantSettlementDetail toSave) {
		final EntityManager em = EMF.get().createEntityManager();
		try{
			return em.merge(toSave);
		} finally {
			em.close();
		}
	}

	@SuppressWarnings("unchecked")
	public List<Merchant> getByPostCode(String postcode) {
		final EntityManager em = EMF.get().createEntityManager();
		try{
			final Query q = em.createQuery("select m from Merchant m where " +
											"m.postCode >= :POSTCODE1 AND " +
											"m.postCode < :POSTCODE2");
			q.setParameter("POSTCODE1", postcode);
			q.setParameter("POSTCODE2",postcode + "\ufffd");
			return q.getResultList();
		} finally {
			em.close();
		}

	}

	public List<Merchant> getAllMerchants() {
		return merchants;
	}
	
}
